home *** CD-ROM | disk | FTP | other *** search
- #ifdef UNIX
- /*
- * Intelligent session manager using curses. Options include ANSI X3.64
- * emulation with both VTx00 and PC graphics.
- *
- * Brandon S. Allbery KF8NH
- * No copyright, copyleft, copysideways, copytwisted, ....
- */
-
- #include <sys/types.h>
- #include <errno.h>
- #include <sys/param.h>
- #include "system.h"
- /*lint -save -e659 */
- #ifdef HAVE_NCURSES_H
- #include <ncurses.h>
- #else
- #include <curses.h>
- #endif
- /*lint -restore */
- #ifndef MSDOS
- #include <term.h>
- #endif
- #undef FALSE
- #undef TRUE
-
- #ifndef _lint
- static char rcsid[] OPTIONAL = "$Id: curses.c,v 1.20 1997/08/19 01:19:22 root Exp root $";
- #endif
-
- # ifndef wbkgdset
- # define wbkgdset(w,attr) ((w)->_bkgd = (attr))
- # endif
- # ifndef getattrs
- # define getattrs(w) ((w)->_attrs)
- # endif
-
-
- #ifdef memcpy
- #undef memcpy
- #endif
-
- #include "global.h"
- #include "hardware.h"
- #include "proc.h"
- #undef tputs
- #include "tty.h"
- /*lint -e123 */
- #include "sessmgr.h"
-
- /* This nonsense WILL go away... */
- #ifdef NO_CURSES_TMARG
- # define _tmarg _regtop
- # define _bmarg _regbottom
- #endif
-
- #ifdef SM_CURSES
-
- #ifdef SCREENSAVER
- extern void sskick (void);
- #endif
-
- extern struct sessmgr_sw curses_sessmgr; /* forward declaration */
-
- static int Suspense, initted;
- #ifdef RAW_SESSMGR
- static TERMINAL *my_term;
- #endif
- static void *curscreen;
- extern int Numrows, Numcols;
- extern int Keyboard;
- extern int SYSback, SYSfore;
-
-
- /* colors - this is a mess */
- static int *color_pair_map;
-
-
- struct keytrie
- {
- enum {KT_DEF, KT_TRIE, KT_TVAL, KT_VAL} kt_type; /* type of entry */
- int kt_tval; /* if a TVAL, the timed-out value */
- union
- {
- struct keytrie *ktu_trie; /* sub-trie */
- #define kt_trie kt_u.ktu_trie
- int ktu_val; /* value */
- #define kt_val kt_u.ktu_val
- } kt_u;
- };
-
-
- struct curses_data
- {
- WINDOW *win;
- struct
- {
- int x, y, tmarg, bmarg, valid;
- chtype attr, bkgrnd;
- } save;
- char parm[8];
- char nparm;
- char bg; /* current background */
- char fg; /* current foreground */
- char flags;
- #define C_ESC 0x01
- #define C_CSI 0x02
- #define C_INS 0x04
- #define C_TTY 0x08
- #define C_BOLD 0x10
- };
-
-
- static struct keytrie *keys;
-
- /* mapping of IBM line-drawing characters to curses line drawing */
- /* this is evil: it doesn't use e.g. ACS_HLINE because that's an array ref */
- static chtype ibm_map[128] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 'a', 'a', 'a', 'x', 'u', 'u', 'u', 'k',
- 'k', 'u', 'x', 'k', 'j', 'j', 'j', 'k',
- 'm', 'v', 'w', 'u', 'q', 'n', 'u', 'u',
- 'j', 'l', 'v', 'w', 'u', 'q', 'n', 'v',
- 'v', 'w', 'w', 'm', 'm', 'l', 'l', 'n',
- 'n', 'j', 'l', 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
-
-
- /*lint -save -e550 */
- static int
- Getmaxy (WINDOW *w)
- {
- int y, x;
-
- getmaxyx(w, y, x);
- return y;
- }
-
- static int
- Getmaxx (WINDOW *w)
- {
- int y, x;
-
- getmaxyx(w, y, x);
- return x;
- }
- /*lint -restore */
-
-
-
- static struct keytrie *
- key_init (void)
- {
- struct keytrie *k;
- int i;
-
- k = mallocw(256 * sizeof *keys);
- for (i = 256; i--; ) {
- k[i].kt_type = KT_DEF;
- k[i].kt_val = i;
- }
- return k;
- }
-
-
-
- static void
- key_add (const char *str, int val)
- {
- struct keytrie *t;
- int c;
-
- /*
- * Follow the trie until we get to the right subtrie for the string, then
- * add the value. If we hit a KT_DEF, expand the trie. If we hit a KT_VAL
- * change it to a KT_TVAL, which times out as a KT_VAL but continues as a
- * KT_TRIE. If given a value for a KT_TRIE, change it to a KT_TVAL.
- */
- if (!str || !*str)
- return; /* no key to define */
- t = keys;
- while (str[1]) {
- c = uchar(*str++);
- if (t[c].kt_type != KT_TRIE) {
- if (t[c].kt_type == KT_DEF)
- t[c].kt_type = KT_TRIE;
- else {
- t[c].kt_type = KT_TVAL;
- t[c].kt_tval = t[c].kt_val;
- }
- t[c].kt_trie = key_init();
- }
- t = t[c].kt_trie;
- }
- c = uchar(*str);
- if (t[c].kt_type == KT_TRIE) {
- t[c].kt_type = KT_TVAL;
- t[c].kt_tval = val;
- } else if (t[c].kt_type == KT_DEF) {
- t[c].kt_type = KT_VAL;
- t[c].kt_val = val;
- }
- }
-
- /*lint -restore */
-
-
-
- static int
- map_colors(int bg, int fg)
- {
- int cp, cmask;
-
- if (!color_pair_map)
- return 0;
- #ifdef DEBUGCOLOR
- fprintf (stderr, "map_colors %d %d", bg, fg);
- #endif
- cmask = (int) ((unsigned int) bg << 4) | fg;
- for (cp = 0; cp < COLOR_PAIRS; cp++) {
- if (color_pair_map[cp] == -1 || color_pair_map[cp] == cmask)
- break;
- }
-
- if (cp == COLOR_PAIRS) {
- #ifdef DEBUGCOLOR
- fprintf(stderr, " - out of pairs!\n");
- #endif
- return 0;
- }
-
- if (color_pair_map[cp] == -1) {
- if (init_pair((short)(cp + 1), (short) fg, (short) bg) == ERR) {
- #ifdef DEBUGCOLOR
- fprintf(stderr, "can't create pair %d\n", cp);
- #endif
- cp = 0;
- } else {
- #ifdef DEBUGCOLOR
- fprintf(stderr, " - new pair %d\n", cp);
- #endif
- color_pair_map[cp] = cmask;
- }
- }
- #ifdef DEBUGCOLOR
- else
- fprintf(stderr, " is pair %d\n", cp);
- #endif
- return ((int) COLOR_PAIR((unsigned int)(cp + 1)));
- }
-
-
-
- static int
- curses_init(const struct sessmgr_sw *sm OPTIONAL)
- {
- if (!isatty(0))
- return 0;
- if (initted) {
- #ifdef RAW_SESSMGR
- set_curterm(my_term);
- #endif
- (void) refresh(); /* bring curses back to life */
- } else {
- (void) initscr(); /* be nice to trap errors... */
- /*
- * I assume the curses manpage tells the truth when it claims that
- * colors are initialized to RGB defaults. If not, I may need to set
- * up the colors in question...
- */
- if (has_colors() && start_color() != ERR && COLORS >= 8) {
- color_pair_map = mallocw((unsigned int)COLOR_PAIRS * sizeof(int));
- memset(color_pair_map, -1, ((unsigned int) COLOR_PAIRS) * sizeof(int));
- (void) map_colors(SYSback, SYSfore); /* default color pair */
- }
- #ifdef RAW_SESSMGR
- my_term = cur_term;
- #endif
- (void) noecho();
- (void) nonl();
- (void) raw();
- keys = key_init();
- key_add(key_down, DNARROW);
- key_add(key_f1, -3);
- key_add(key_f2, -4);
- key_add(key_f3, -5);
- key_add(key_f4, -6);
- key_add(key_f5, -7);
- key_add(key_f6, -8);
- key_add(key_f7, -9);
- key_add(key_f8, -10);
- key_add(key_f9, -11);
- key_add(key_ic, -105);
- key_add(key_dc, -106);
- key_add(key_home, -107);
- key_add(key_end, -108);
- key_add(key_ppage, -109);
- key_add(key_npage, -110);
- key_add(key_f10, -2);
- key_add(key_left, LTARROW);
- key_add(key_right, RTARROW);
- key_add(key_up, UPARROW);
- key_add("\177", '\b'); /* so DEL behaves as BS */
- initted = 1;
- }
- Suspense = 0;
- Numrows = LINES;
- Numcols = COLS;
- return 1;
- }
-
-
-
- static void
- curses_end (const struct sessmgr_sw *sm OPTIONAL)
- {
- if (!Suspense)
- (void) endwin();
- }
-
-
-
- static void
- curses_suspend (const struct sessmgr_sw *sm OPTIONAL)
- {
- if (!Suspense++) {
- /* note that we use stdscr for this, since it's otherwise unoccupied */
- (void) clear();
- (void) refresh();
- (void) endwin();
- }
- }
-
-
-
- static void
- curses_resume(const struct sessmgr_sw *sm OPTIONAL)
- {
- if (!--Suspense) {
- #ifdef RAW_SESSMGR
- set_curterm(my_term);
- #endif
- (void) clearok(((struct curses_data *) curscreen)->win, TRUE);
- (void) wrefresh(((struct curses_data *) curscreen)->win);
- Numrows = LINES;
- Numcols = COLS;
- }
- }
-
-
-
- /*
- * Options supported:
- *
- * tty, ansi
- * Select old glass-tty emulation or new ANSI X3.64 emulation
- *
- * bold
- * Specify style of highlight used
- */
-
- static char *
- curses_opts(const struct sessmgr_sw *sm OPTIONAL, void *sp, const char *opts)
- {
- struct curses_data *cp;
- static char buf[1024];
- char const *ep;
- char const *xp;
- size_t l;
-
- cp = (struct curses_data *) sp;
- if (!opts) {
- /* return printable version of options */
- buf[0] = '\0';
- if (cp->flags & C_TTY)
- strcpy(buf, "tty");
- if ((cp->flags & (C_TTY|C_BOLD)) == (C_TTY|C_BOLD))
- strcat(buf, ",");
- if (cp->flags & C_BOLD)
- strcat(buf, "bold");
- return buf;
- }
-
- /* parse and set options */
- xp = opts;
- while (*xp) {
- while (isspace(*xp) || *xp == ',')
- xp++;
- if (!*xp)
- break;
- l = 0;
- for (ep = xp; *ep && *ep != ',' && !isspace(*ep); ep++)
- l++;
- memcpy(buf, xp, l);
- buf[l] = '\0';
- if (strcasecmp(buf, "tty") == 0)
- cp->flags |= C_TTY;
- else if (strcasecmp(buf, "ansi") == 0)
- cp->flags &= ~C_TTY;
- else if (strcasecmp(buf, "notty") == 0)
- cp->flags &= ~C_TTY;
- else if (strcasecmp(buf, "noansi") == 0)
- cp->flags |= C_TTY;
- else if (strcasecmp(buf, "bold") == 0)
- cp->flags |= C_BOLD;
- else if (strcasecmp(buf, "nobold") == 0)
- cp->flags &= ~C_BOLD;
- else
- tprintf("curses: unknown option \"%s\"\n", buf);
- xp = ep;
- }
-
- return 0;
- }
-
-
-
- static int
- curses_swap (const struct sessmgr_sw *sm OPTIONAL, void *old OPTIONAL, void *new)
- {
- if (new) {
- (void) clearok(((struct curses_data *) new)->win, TRUE);
- (void) touchwin(((struct curses_data *) new)->win);
- curscreen = new;
- }
- return 1; /* can always run concurrent output */
- }
-
-
-
- static void
- wiach (WINDOW *win, chtype ch, int insert)
- {
- if (insert)
- (void) winsch(win, (chtype) ch);
- else
- (void) waddch(win, (chtype) ch);
- }
-
-
-
- static void
- curses_flush (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- if (!Suspense && curscreen == dp)
- (void) wrefresh(((struct curses_data *) dp)->win);
- }
-
-
-
- static void
- curses_putch (const struct sessmgr_sw *sm OPTIONAL, void *dp, int c)
- {
- register struct curses_data *sp;
- int x, y, ox, oy;
- chtype attrs;
-
- sp = dp;
- if (c == 7) {
- write(1, "\7", 1);
- return;
- }
-
- #ifdef SCREENSAVER
- sskick();
- #endif
-
- if (c == '\r' || c == '\b') {
- (void) waddch(sp->win, (chtype) c);
- return;
- }
- if (c == '\t') {
- wiach(sp->win, (chtype) c, sp->flags & C_INS);
- return;
- }
- if (c == '\n') {
- /* waddch() does clrtoeol() implicitly. This breaks us. */
- getyx(sp->win, y, x);
- if (++y > sp->win->_bmarg) {
- y--;
- (void) scroll(sp->win);
- #if 1
- if (Curproc->session->screen->flags & SMS_ACTIVE)
- #if 0
- (void) wrefresh (sp->win);
- #else
- curses_flush (sm, dp);
- #endif
- #endif
- }
- (void) wmove(sp->win, y, 0);
- return;
- }
- if (sp->flags & C_TTY) {
- if (c >= 32 && c < 127)
- wiach(sp->win, (chtype) c, sp->flags & C_INS);
- return;
- }
- if (c == 24 || c == 26) {
- sp->flags &= ~(C_ESC|C_CSI);
- return;
- }
- if (c == 27) {
- sp->flags |= C_ESC;
- return;
- }
- if (c == '\016') {
- (void) wattron(sp->win, A_ALTCHARSET);
- return;
- }
- if (c == '\017') {
- (void) wattroff(sp->win, A_ALTCHARSET);
- return;
- }
- if (c < 32)
- return;
- if (!(sp->flags & (C_ESC|C_CSI))) {
- if (c > 127 && ibm_map[c - 128])
- wiach(sp->win, ibm_map[c - 128] | A_ALTCHARSET, sp->flags & C_INS);
- else if (c < 127)
- wiach(sp->win, (chtype) c, sp->flags & C_INS);
- return;
- }
- if (sp->flags & C_ESC) {
- /* we only handle '[' */
- switch (c) {
- case '[':
- sp->flags &= ~C_ESC;
- sp->flags |= C_CSI;
- sp->nparm = 0;
- memset(sp->parm, 0, sizeof sp->parm);
- break;
- case '7':
- getyx(sp->win, sp->save.y, sp->save.x);
- sp->save.attr = getattrs(sp->win);
- sp->save.tmarg = sp->win->_tmarg;
- sp->save.bmarg = sp->win->_bmarg;
- sp->save.bkgrnd = sp->win->_bkgd; /* should be a macro for this */
- sp->save.valid = 1;
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case '8':
- if (sp->save.valid) {
- (void) wmove(sp->win, sp->save.y, sp->save.x);
- wattrset(sp->win, sp->save.attr);
- wbkgdset(sp->win, sp->save.bkgrnd);
- #ifdef linux
- (void) werase(sp->win); /* wbkgdset() doesn't do anything */
- #endif
- (void) wsetscrreg(sp->win, sp->save.tmarg, sp->save.bmarg);
- sp->save.valid = 0;
- }
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- default:
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- }
- return;
- }
-
- /* handle CSI-sequences */
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- sp->parm[(int)sp->nparm] = (char) (sp->parm[(int)sp->nparm] * 10 + c - '0');
- break;
- case ';':
- sp->parm[(int)(sp->nparm++)] = 0;
- break;
- case '?':
- /* just ignore it for now */
- break;
- /* action character */
- case 'H':
- case 'f':
- (void) wmove(sp->win, sp->parm[1] - 1, sp->parm[0] - 1);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'J':
- switch (sp->parm[0]) {
- case 0:
- attrs = getattrs(sp->win);
- wattrset(sp->win, A_NORMAL);
- (void) wclrtobot(sp->win);
- wattrset(sp->win, attrs);
- break;
- case 1:
- getyx(sp->win, oy, ox);
- attrs = getattrs(sp->win);
- wattrset(sp->win, A_NORMAL);
- for (y = 0; y < oy; y++) {
- (void) wmove(sp->win, y, 0);
- for (x = Getmaxx(sp->win); x--; )
- (void) waddch(sp->win, ' ');
- }
- (void) wmove(sp->win, oy, 0);
- for (x = 0; x < ox; x++)
- (void) waddch(sp->win, ' ');
- wattrset(sp->win, attrs);
- break;
- case 2:
- (void) wclear(sp->win);
- break;
- default:
- break;
- }
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'K':
- switch (sp->parm[0]) {
- case 0:
- (void) clrtoeol();
- break;
- case 1:
- getyx(sp->win, oy, ox);
- (void) wmove(sp->win, oy, 0);
- attrs = getattrs(sp->win);
- wattrset(sp->win, A_NORMAL);
- for (x = 0; x < ox; x++)
- (void) waddch(sp->win, ' ');
- wattrset(sp->win, attrs);
- break;
- case 2:
- getyx(sp->win, oy, ox);
- (void) wmove(sp->win, oy, 0);
- attrs = getattrs(sp->win);
- wattrset(sp->win, A_NORMAL);
- for (x = Getmaxx(sp->win); x--; )
- (void) waddch(sp->win, ' ');
- (void) wmove(sp->win, oy, ox);
- wattrset(sp->win, attrs);
- break;
- default:
- break;
- }
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'm':
- sp->flags &= ~(C_ESC|C_CSI);
- if (!sp->nparm) {
- (void) wattroff(sp->win, A_BOLD|A_DIM|A_UNDERLINE|A_BLINK|A_REVERSE);
- break;
- }
- for (x = 0; x < sp->nparm; x++) {
- switch (sp->parm[x]) {
- case 0:
- (void) wattroff(sp->win, A_BOLD|A_DIM|A_UNDERLINE|A_BLINK|A_REVERSE);
- break;
- case 1:
- (void) wattron(sp->win, A_BOLD);
- break;
- case 2:
- (void) wattron(sp->win, A_DIM);
- break;
- case 4:
- (void) wattron(sp->win, A_UNDERLINE);
- break;
- case 5:
- (void) wattron(sp->win, A_BLINK);
- break;
- case 7:
- (void) wattron(sp->win, A_REVERSE);
- break;
- case 21:
- (void) wattroff(sp->win, A_BOLD);
- break;
- case 22:
- (void) wattroff(sp->win, A_DIM);
- break;
- case 24:
- (void) wattroff(sp->win, A_UNDERLINE);
- break;
- case 25:
- (void) wattroff(sp->win, A_BLINK);
- break;
- case 27:
- (void) wattroff(sp->win, A_REVERSE);
- break;
- /* ANSI color sequences? */
- /* not for now; curses colors are too complex */
- default:
- break;
- }
- }
- break;
- case 'A':
- getyx(sp->win, y, x);
- if ((y -= (sp->nparm? sp->parm[0]: 1)) < 0)
- y = 0;
- (void) wmove(sp->win, y, x);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'B':
- getyx(sp->win, y, x);
- if ((y += (sp->nparm? sp->parm[0]: 1)) >= Getmaxy(sp->win))
- y = Getmaxy(sp->win) - 1;
- (void) wmove(sp->win, y, x);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'C':
- getyx(sp->win, y, x);
- if ((x += (sp->nparm? sp->parm[0]: 1)) >= Getmaxx(sp->win))
- x = Getmaxx(sp->win) - 1;
- (void) wmove(sp->win, y, x);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'D':
- getyx(sp->win, y, x);
- if ((x -= (sp->nparm? sp->parm[0]: 1)) < 0)
- x = 0;
- (void) wmove(sp->win, y, x);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'r':
- (void) wsetscrreg(sp->win, (sp->nparm? sp->parm[0] - 1: 0),
- (sp->nparm > 1? sp->parm[1] - 1: Getmaxy(sp->win) - 1));
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 's':
- getyx(sp->win, sp->save.y, sp->save.x);
- sp->save.attr = getattrs(sp->win);
- sp->save.tmarg = sp->win->_tmarg;
- sp->save.bmarg = sp->win->_bmarg;
- sp->save.bkgrnd = sp->win->_bkgd; /* should be a macro for this */
- sp->save.valid = 1;
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'u':
- if (sp->save.valid) {
- (void) wmove(sp->win, sp->save.y, sp->save.x);
- wattrset(sp->win, sp->save.attr);
- wbkgdset(sp->win, sp->save.bkgrnd);
- (void) wsetscrreg(sp->win, sp->save.tmarg, sp->save.bmarg);
- sp->save.valid = 0;
- }
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'L':
- if (!sp->nparm)
- sp->parm[0] = 1;
- while (sp->parm[0]--)
- (void) winsertln(sp->win);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'M':
- if (!sp->nparm)
- sp->parm[0] = 1;
- while (sp->parm[0]--)
- (void) wdeleteln(sp->win);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case '@':
- if (!sp->nparm)
- sp->parm[0] = 1;
- while (sp->parm[0]--)
- (void) winsch(sp->win, ' ');
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'P':
- if (!sp->nparm)
- sp->parm[0] = 1;
- while (sp->parm[0]--)
- (void) wdelch(sp->win);
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- case 'h':
- case 'l':
- for (x = 0; x < sp->nparm; x++) {
- switch (sp->parm[x]) {
- case 4:
- if (c == 'h')
- sp->flags |= C_INS;
- else
- sp->flags &= ~C_INS;
- break;
- /* insert mode is all we handle right now */
- default:
- break;
- }
- }
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- default:
- sp->flags &= ~(C_ESC|C_CSI);
- break;
- }
- }
-
-
-
- static void
- curses_clreol (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- #ifdef SCREENSAVER
- sskick();
- #endif
- (void) wclrtoeol(((struct curses_data *) dp)->win);
- }
-
-
-
- static void
- curses_rflush (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
- {
- /* stub - later we'll update status here */
- }
-
-
-
- static void *
- curses_create (const struct sessmgr_sw *sm OPTIONAL, struct session *sp OPTIONAL)
- {
- struct curses_data *ssp;
-
- ssp = mallocw(sizeof *ssp);
- ssp->win = newwin(LINES, COLS, 0, 0);
- (void) scrollok(ssp->win, TRUE);
-
- ssp->bg = (char) SYSback; /* witness help 'em if they're in an xterm */
- ssp->fg = (char) SYSfore;
- (void) wbkgd(ssp->win, COLOR_PAIR(1));
- wattrset(ssp->win, COLOR_PAIR(1));
-
- ssp->flags = 0;
- ssp->save.valid = 0;
- curscreen = ssp;
- return ssp;
- }
-
-
-
- static void
- curses_destroy (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- (void) delwin(((struct curses_data *) dp)->win);
- j_free(dp);
- }
-
-
-
- static void
- curses_clrscr (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- WINDOW *w;
- int l;
-
- #ifdef SCREENSAVER
- sskick();
- #endif
- w = ((struct curses_data *) dp)->win;
-
- /* This CANNOT be a simple 'wclear (w)', as that clears
- the current 'window' AND the rest of the screen. This
- code properly honors the active 'window'.
- */
- for (l = w->_tmarg; l <= w->_bmarg; l++) {
- (void) wmove(w, l, 0);
- (void) wclrtoeol(w);
- }
-
- (void) wmove(w, w->_tmarg, 0);
- }
-
-
-
- /*lint -save -e550 */
- static int
- curses_wherex (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- int x, y;
-
- getyx(((struct curses_data *) dp)->win, y, x);
- return x + 1;
- }
-
-
-
- static int
- curses_wherey (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- WINDOW *w;
- int x, y;
-
- w = ((struct curses_data *) dp)->win;
- getyx(w, y, x);
- return y - w->_tmarg + 1;
- }
-
- /*lint -restore */
-
-
-
- static void
- curses_window (const struct sessmgr_sw *sm OPTIONAL, void *dp, int x1 OPTIONAL,
- int y1, int x2 OPTIONAL, int y2)
- {
- WINDOW *w;
-
- w = ((struct curses_data *) dp)->win;
- (void) wsetscrreg(w, y1 - 1, y2 - 1);
- /* ttydriv() assumes the cursor is placed in this window somewhere */
- (void) wmove(w, y1 - 1, 0);
- }
-
-
-
- static void
- curses_gotoxy (const struct sessmgr_sw *sm OPTIONAL, void *dp, int x, int y)
- {
- WINDOW *w;
-
- w = ((struct curses_data *) dp)->win;
- (void) wmove(w, y + w->_tmarg - 1, x - 1);
- }
-
-
-
- static void
- curses_high (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- (void) wattron(((struct curses_data *) dp)->win,
- (unsigned)((((struct curses_data *) dp)->flags & C_BOLD)? A_BOLD: A_REVERSE));
- }
-
- static void
- curses_norm (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- (void) wattroff(((struct curses_data *) dp)->win,
- (((struct curses_data *) dp)->flags & C_BOLD)? A_BOLD: A_REVERSE);
- }
-
-
-
- static void
- curses_txtattr (const struct sessmgr_sw *sm OPTIONAL, void *dp, int color)
- {
- (void) init_pair (1, color & 0x0f, ((unsigned int) color >> 4) & 0x0f);
- wattrset (((struct curses_data *) dp)->win, COLOR_PAIR(1));
- }
-
-
-
- static void
- curses_refresh (const struct sessmgr_sw *sm OPTIONAL, void *dp)
- {
- (void) clearok(((struct curses_data *) dp)->win, TRUE);
- (void) wrefresh (((struct curses_data *) dp)->win);
- }
-
-
-
- static void
- curses_bground (const struct sessmgr_sw *sm OPTIONAL, void *dp, int color)
- {
- ((struct curses_data *) dp)->bg = (char) color;
- curses_txtattr (sm, dp, ((int) (((unsigned int)color) << 4) | (int)((struct curses_data *) dp)->fg));
- (void) wbkgd (((struct curses_data *) dp)->win, COLOR_PAIR(1));
- }
-
-
- static void
- curses_fground (const struct sessmgr_sw *sm OPTIONAL, void *dp, int color)
- {
- ((struct curses_data *) dp)->fg = (char) color;
- curses_txtattr (sm, dp, (int) ((int) (((unsigned int) (int) ((struct curses_data *) dp)->bg) << 4) | color));
- (void) wbkgd (((struct curses_data *) dp)->win, COLOR_PAIR(1));
- }
-
-
-
- static void
- curses_cursor (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c)
- {
- (void) curs_set(c);
- }
-
-
-
- static int
- kbchar(int ir)
- {
- unsigned char ch;
- int i;
-
- if (ir)
- kalarm(500);
- do {
- if (kwait(&Keyboard) != 0 && ir)
- return -1;
- }
- while ((i = read(0, &ch, 1)) == 0 || (i == -1 && errno == EWOULDBLOCK))
- ;
- kalarm(0);
- if (i < 0) {
- tprintf("NOS PANIC: Lost keyboard\n");
- where_outta_here(1, "kbchar");
- }
- return ch;
- }
-
-
-
- /*
- * This remains incorrect. The keyboard process must be recreated as part of
- * the session manager instead of being independent; this process must be
- * capable of distributing input from several sources, including the real
- * keyboard and external sessions.
- */
-
- static int
- curses_kbread(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
- {
- static int ungets[10];
- struct keytrie *t;
- static int unget = 0;
- int theungetc[10];
- int c, i, u;
-
- i = 0;
- u = 0;
- if (unget > i)
- c = ungets[i++]; /*lint !e727 */
- else
- c = kbchar(0);
- theungetc[u++] = c;
- t = keys;
- while (t[c].kt_type == KT_TRIE || t[c].kt_type == KT_TVAL) {
- t = t[c].kt_trie;
- if (unget > i)
- c = ungets[i++];
- else
- c = kbchar(1);
- if (c == -1)
- break;
- theungetc[u++] = c;
- }
-
- if (t[c].kt_type == KT_VAL) {
- u = 0;
- c = t[c].kt_val;
- } else if (t[c].kt_type == KT_TVAL) {
- u = 0;
- c = t[c].kt_tval;
- }
-
- while (i < unget)
- theungetc[u++] = ungets[i++];
- if (u) {
- c = theungetc[0];
- for (i = u; i; i--)
- ungets[i - 1] = theungetc[i];
- unget = u - 1;
- }
- return c;
- }
-
-
-
- struct sessmgr_sw curses_sessmgr =
- {
- "curses",
- SM_SPLIT|SM_STDIO,
- curses_init,
- (char *(*)(const struct sessmgr_sw *, char *)) 0,
- curses_create,
- curses_opts,
- curses_swap,
- curses_putch,
- curses_clreol,
- curses_clrscr,
- curses_wherex,
- curses_wherey,
- curses_window,
- curses_gotoxy,
- curses_high,
- curses_norm,
- curses_bground,
- curses_fground,
- curses_txtattr,
- curses_refresh,
- curses_cursor,
- curses_kbread,
- curses_destroy,
- 0,
- curses_rflush,
- curses_flush,
- curses_suspend,
- curses_resume,
- curses_end,
- 0
- };
-
- #endif
-
- #endif /* UNIX */
-